package gui;

import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import model.Stack;
import service.LocationNotFoundException;
import service.Service;
import dao.Dao;

public class StackInfoDialog extends JDialog {
    private Stack stack;
    private JLabel lblName, lblTrays, lblCurrentProcess, lblNextProcess,
	    lblWarning;
    private JTextField txfName, txfTrays, txfCurrentProcess, txfNextProcess;
    private JButton btnShowTasks, btnContinue, btnEdit;
    private JPanel contentPane = new JPanel();
    private Component owner;
    private CustomActionListener actionListener = new CustomActionListener();

    public StackInfoDialog(Stack stack, Component owner) {
	setContentPane(contentPane);
	getContentPane().setLayout(null);

	setTitle("Stack info");
	setResizable(false);
	// setModal(true);

	setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
	this.stack = stack;
	this.owner = owner;

	setLocation(400, 200);
	setSize(400, 300);

	lblName = new JLabel("Name");
	lblTrays = new JLabel("Number of trays");
	lblCurrentProcess = new JLabel("Current process");
	lblNextProcess = new JLabel("Next process");
	txfName = new JTextField(stack.getProductType().getName());
	txfTrays = new JTextField(Integer.toString(stack.getNumberOfTrays()));
	txfCurrentProcess = new JTextField(stack.getCurrentProcess()
		.getProcess().getName());
	txfNextProcess = new JTextField(stack.getNextProcess() != null ? stack
		.getNextProcess().getProcess().getName() : "No process");

	txfName.setEditable(false);
	txfTrays.setEditable(false);
	txfCurrentProcess.setEditable(false);
	txfNextProcess.setEditable(false);

	lblName.setSize(180, 20);
	lblTrays.setSize(180, 20);
	lblCurrentProcess.setSize(180, 20);
	lblNextProcess.setSize(180, 20);
	txfName.setSize(180, 20);
	txfTrays.setSize(180, 20);
	txfCurrentProcess.setSize(180, 20);
	txfNextProcess.setSize(180, 20);

	lblName.setLocation(20, 20);
	lblTrays.setLocation(20, 50);
	lblCurrentProcess.setLocation(20, 80);
	lblNextProcess.setLocation(20, 110);
	txfName.setLocation(190, 20);
	txfTrays.setLocation(190, 50);
	txfCurrentProcess.setLocation(190, 80);
	txfNextProcess.setLocation(190, 110);

	lblWarning = new JLabel();
	lblWarning.setLocation(20, 140);
	lblWarning.setSize(350, 50);

	long past = System.currentTimeMillis()
		- stack.getCurrentProcess().getStartTime().getTime();

	if (past < stack.getCurrentProcess().getProcess().getMinTime()) {
	    lblWarning
		    .setText("<html>Be careful! The running time of this process has not reached a minimum time yet! Passed: "
			    + Service.getInstance().milisToTime(past)
			    + "; Minimum time: "
			    + Service.getInstance().milisToTime(
				    stack.getCurrentProcess().getProcess()
					    .getMinTime()) + "</html>");
	} else if ((past >= stack.getCurrentProcess().getProcess().getMinTime())
		&& (past <= stack.getCurrentProcess().getProcess().getMaxTime())) {
	    lblWarning
		    .setText("<html>It is safe to run the next process now! Passed: "
			    + Service.getInstance().milisToTime(past)
			    + "; Minimum time: "
			    + Service.getInstance().milisToTime(
				    stack.getCurrentProcess().getProcess()
					    .getMinTime())
			    + "; Maximum time: "
			    + Service.getInstance().milisToTime(
				    stack.getCurrentProcess().getProcess()
					    .getMaxTime()) + "</html>");
	} else {
	    lblWarning
		    .setText("<html>That's too late to run the next process :( The stack will move to wastes. Passed: "
			    + Service.getInstance().milisToTime(past)
			    + "; Maximum time: "
			    + Service.getInstance().milisToTime(
				    stack.getCurrentProcess().getProcess()
					    .getMaxTime()) + "</html>");
	}

	lblWarning.setForeground(Color.RED);

	contentPane.add(lblName);
	contentPane.add(lblTrays);
	contentPane.add(lblCurrentProcess);
	contentPane.add(lblNextProcess);
	contentPane.add(txfName);
	contentPane.add(txfTrays);
	contentPane.add(txfCurrentProcess);
	contentPane.add(txfNextProcess);
	contentPane.add(lblWarning);

	btnShowTasks = new JButton("Show tasks");
	btnShowTasks.setBounds(10, 220, 89, 23);

	btnContinue = new JButton("Continue with next process");
	btnContinue.setBounds(190, 220, 180, 23);

	btnShowTasks.addActionListener(actionListener);
	btnContinue.addActionListener(actionListener);

	contentPane.add(btnShowTasks);
	contentPane.add(btnContinue);

	btnEdit = new JButton("Edit");
	btnEdit.setBounds(111, 220, 67, 23);
	contentPane.add(btnEdit);
	btnEdit.addActionListener(actionListener);

	if (Dao.getInstance().getWastes().contains(stack)) {
	    btnContinue.setEnabled(false);
	    btnEdit.setEnabled(false);
	    lblCurrentProcess.setText("Failed process");
	    lblNextProcess.setText("Failed at");
	    txfNextProcess.setText(Service.getInstance().displayTime(
		    stack.getCurrentProcess().getFinishTime()));
	    lblWarning.setText("This stack is wasted.");
	} else if (Dao.getInstance().getFinished().contains(stack)) {
	    btnContinue.setEnabled(false);
	    btnEdit.setEnabled(false);
	    lblWarning.setText("This stack is finished.");
	}

    }

    public void updateStackInfo() {
	txfTrays.setText(Integer.toString(stack.getNumberOfTrays()));
    }

    private class CustomActionListener implements ActionListener {
	@Override
	public void actionPerformed(ActionEvent e) {
	    if (e.getSource() == btnContinue) {
		try {
		    Service.getInstance().nextProcess(stack);
		    StackInfoDialog.this.dispose();
		} catch (LocationNotFoundException e1) {
		    // TODO Auto-generated catch block
		    e1.printStackTrace();
		}
	    } else if (e.getSource() == btnShowTasks) {
		TaskListDialog tlDialog = new TaskListDialog(
			StackInfoDialog.this.stack);
		tlDialog.setVisible(true);
	    } else if (e.getSource() == btnEdit) {
		EditStack es = new EditStack(StackInfoDialog.this,
			StackInfoDialog.this.stack);
	    }
	}
    }
}
